import React, { useState, useRef } from 'react';
import {
    Box,
    Typography,
    Button,
    LinearProgress,
    Paper,
    IconButton,
    Alert,
    AlertTitle,
    Tooltip
} from '@mui/material';
import {
    CloudUpload as CloudUploadIcon,
    Close as CloseIcon,
    InsertDriveFile as FileIcon,
    CheckCircleOutline as CheckIcon
} from '@mui/icons-material';
import { motion, AnimatePresence } from 'framer-motion';
import { styled } from '@mui/material/styles';

const VisuallyHiddenInput = styled('input')({
    clip: 'rect(0 0 0 0)',
    clipPath: 'inset(50%)',
    height: 1,
    overflow: 'hidden',
    position: 'absolute',
    bottom: 0,
    left: 0,
    whiteSpace: 'nowrap',
    width: 1,
});

const DropZone = styled(Paper)(({ theme, isDragActive, isDragReject }) => ({
    padding: theme.spacing(4),
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    borderStyle: 'dashed',
    borderWidth: 2,
    borderRadius: theme.shape.borderRadius,
    borderColor: isDragActive
        ? theme.palette.primary.main
        : isDragReject
            ? theme.palette.error.main
            : theme.palette.divider,
    backgroundColor: isDragActive
        ? `${theme.palette.primary.main}10`
        : isDragReject
            ? `${theme.palette.error.main}10`
            : theme.palette.background.default,
    cursor: 'pointer',
    transition: 'all 0.3s ease',
    minHeight: 200
}));

const FileUpload = ({
    onUpload,
    accept = '.glb,.obj,.stl,.fbx',
    maxSize = 50 * 1024 * 1024, // 50MB
    progress = 0,
    isUploading = false,
    error = null,
}) => {
    const [dragActive, setDragActive] = useState(false);
    const [dragReject, setDragReject] = useState(false);
    const [selectedFile, setSelectedFile] = useState(null);
    const [fileError, setFileError] = useState(null);
    const inputRef = useRef(null);

    const handleDrag = (e) => {
        e.preventDefault();
        e.stopPropagation();

        if (e.type === 'dragenter' || e.type === 'dragover') {
            setDragActive(true);

            // 检查文件类型
            if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
                const item = e.dataTransfer.items[0];
                const fileExtension = `.${item.type.split('/')[1]}`;
                if (!accept.includes(fileExtension) && item.type !== 'application/octet-stream') {
                    setDragReject(true);
                } else {
                    setDragReject(false);
                }
            }
        } else if (e.type === 'dragleave') {
            setDragActive(false);
            setDragReject(false);
        }
    };

    const validateFile = (file) => {
        // 检查文件大小
        if (file.size > maxSize) {
            setFileError(`文件大小超过限制 (最大 ${maxSize / (1024 * 1024)}MB)`);
            return false;
        }

        // 检查文件类型
        const fileExtension = `.${file.name.split('.').pop().toLowerCase()}`;
        if (!accept.split(',').some(ext => fileExtension === ext.trim())) {
            setFileError(`不支持的文件类型，请上传 ${accept} 格式的文件`);
            return false;
        }

        setFileError(null);
        return true;
    };

    const handleDrop = (e) => {
        e.preventDefault();
        e.stopPropagation();
        setDragActive(false);
        setDragReject(false);

        if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
            const file = e.dataTransfer.files[0];
            if (validateFile(file)) {
                setSelectedFile(file);
            }
        }
    };

    const handleFileChange = (e) => {
        if (e.target.files && e.target.files.length > 0) {
            const file = e.target.files[0];
            if (validateFile(file)) {
                setSelectedFile(file);
            }
        }
    };

    const handleUpload = () => {
        if (selectedFile && onUpload) {
            onUpload(selectedFile);
        }
    };

    const handleClearFile = () => {
        setSelectedFile(null);
        setFileError(null);
        if (inputRef.current) {
            inputRef.current.value = '';
        }
    };

    const formatFileSize = (bytes) => {
        if (bytes < 1024) return `${bytes} bytes`;
        if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
        return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
    };

    return (
        <Box>
            <AnimatePresence>
                {fileError && (
                    <motion.div
                        initial={{ opacity: 0, y: -10 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0 }}
                        transition={{ duration: 0.3 }}
                    >
                        <Alert
                            severity="error"
                            sx={{ mb: 2 }}
                            action={
                                <IconButton
                                    color="inherit"
                                    size="small"
                                    onClick={() => setFileError(null)}
                                >
                                    <CloseIcon fontSize="small" />
                                </IconButton>
                            }
                        >
                            <AlertTitle>错误</AlertTitle>
                            {fileError}
                        </Alert>
                    </motion.div>
                )}

                {error && (
                    <motion.div
                        initial={{ opacity: 0, y: -10 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0 }}
                        transition={{ duration: 0.3 }}
                    >
                        <Alert
                            severity="error"
                            sx={{ mb: 2 }}
                            action={
                                <IconButton color="inherit" size="small">
                                    <CloseIcon fontSize="small" />
                                </IconButton>
                            }
                        >
                            <AlertTitle>上传失败</AlertTitle>
                            {error}
                        </Alert>
                    </motion.div>
                )}
            </AnimatePresence>

            {!selectedFile ? (
                <DropZone
                    component={motion.div}
                    whileHover={{ boxShadow: '0px 4px 15px rgba(0, 0, 0, 0.08)' }}
                    isDragActive={dragActive}
                    isDragReject={dragReject}
                    onDragEnter={handleDrag}
                    onDragOver={handleDrag}
                    onDragLeave={handleDrag}
                    onDrop={handleDrop}
                    onClick={() => inputRef.current?.click()}
                >
                    <CloudUploadIcon
                        sx={{
                            fontSize: 60,
                            color: dragActive
                                ? 'primary.main'
                                : dragReject
                                    ? 'error.main'
                                    : 'text.secondary',
                            mb: 2
                        }}
                    />
                    <Typography variant="h6" align="center" gutterBottom>
                        拖放文件上传或点击选择
                    </Typography>
                    <Typography variant="body2" align="center" color="textSecondary">
                        支持的格式: {accept.replace(/\./g, '').toUpperCase().split(',').join(', ')}
                    </Typography>
                    <Typography variant="body2" align="center" color="textSecondary">
                        最大文件大小: {maxSize / (1024 * 1024)}MB
                    </Typography>
                    <Button
                        component="label"
                        variant="contained"
                        startIcon={<CloudUploadIcon />}
                        sx={{ mt: 2 }}
                    >
                        选择文件
                        <VisuallyHiddenInput
                            type="file"
                            accept={accept}
                            onChange={handleFileChange}
                            ref={inputRef}
                        />
                    </Button>
                </DropZone>
            ) : (
                <motion.div
                    initial={{ opacity: 0, scale: 0.9 }}
                    animate={{ opacity: 1, scale: 1 }}
                    transition={{ duration: 0.3 }}
                >
                    <Paper sx={{ p: 3, position: 'relative' }}>
                        <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                            <FileIcon color="primary" sx={{ fontSize: 40, mr: 2 }} />
                            <Box sx={{ flexGrow: 1 }}>
                                <Typography variant="subtitle1" noWrap>
                                    {selectedFile.name}
                                </Typography>
                                <Typography variant="body2" color="textSecondary">
                                    {formatFileSize(selectedFile.size)}
                                </Typography>
                            </Box>
                            {!isUploading && (
                                <Tooltip title="移除文件">
                                    <IconButton onClick={handleClearFile} size="small">
                                        <CloseIcon />
                                    </IconButton>
                                </Tooltip>
                            )}
                        </Box>

                        {isUploading ? (
                            <Box sx={{ width: '100%', mt: 1 }}>
                                <LinearProgress
                                    variant="determinate"
                                    value={progress}
                                    sx={{ height: 10, borderRadius: 5 }}
                                />
                                <Typography
                                    variant="body2"
                                    color="textSecondary"
                                    align="center"
                                    sx={{ mt: 1 }}
                                >
                                    上传中... {Math.round(progress)}%
                                </Typography>
                            </Box>
                        ) : (
                            <Button
                                variant="contained"
                                color="primary"
                                fullWidth
                                startIcon={<CloudUploadIcon />}
                                onClick={handleUpload}
                                sx={{ mt: 1 }}
                            >
                                上传文件
                            </Button>
                        )}

                        {progress === 100 && (
                            <Box
                                sx={{
                                    position: 'absolute',
                                    top: 0,
                                    left: 0,
                                    right: 0,
                                    bottom: 0,
                                    display: 'flex',
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    backgroundColor: 'rgba(255, 255, 255, 0.8)',
                                    borderRadius: 1
                                }}
                            >
                                <Box
                                    sx={{
                                        display: 'flex',
                                        flexDirection: 'column',
                                        alignItems: 'center'
                                    }}
                                >
                                    <CheckIcon color="success" sx={{ fontSize: 60, mb: 1 }} />
                                    <Typography variant="h6" color="success.main">
                                        上传成功!
                                    </Typography>
                                </Box>
                            </Box>
                        )}
                    </Paper>
                </motion.div>
            )}
        </Box>
    );
};

export default FileUpload; 